﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using Microsoft.Win32;
using System.Reflection;
using System.Runtime.InteropServices;
using Sunisoft.IrisSkin;

namespace UMD编辑器
{
    public partial class UMDEditorMain : Form
    {
        private const string KEYNAME = "UMD编辑器ByJianyun";
        private const string KEYVALUE = "UMD编辑器 by jianyun";
        private string _fileName;
        private string _path = string.Empty;
        private UMDFile _umdFile = new UMDFile();
        private Chapter _currentChapter;
        private bool IsModified = false;    //标记文本是否做过修改
        private string InitFormTitle = string.Empty;
        private string _currentFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
        SkinEngine skinEngine = new SkinEngine();


        private const uint SHCNE_ASSOCCHANGED = 0x08000000;
        private const uint SHCNF_IDLIST = 0x0000;
        private const uint SHCNF_FLUSH = 0x1000;

        [DllImport("shell32.dll")]
        private static extern void SHChangeNotify(uint wEventId, uint uFlags,
            IntPtr dwItem1, IntPtr dwItem2);

        public UMDEditorMain()
        {
            try
            {
                if (!this.checkIsRegisted()) LinkWithExtension();
                InitializeComponent();

                this.InitFormTitle = this.Text;
                this.richTextBoxContent.Enabled = false;
                this.Text = "无标题" + " - " + this.Text;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        public UMDEditorMain(string file)
        {
            try
            {
                InitializeComponent();

                this.InitFormTitle = this.Text;

                if (!string.IsNullOrEmpty(file))
                {
                    FileInfo fileInfo = new FileInfo(file);
                    this._path = fileInfo.FullName;
                    this._fileName = Path.GetFileNameWithoutExtension(this._path);

                    ReadFile();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void UMDEditorMain_Load(object sender, EventArgs e)
        {
            richTextBoxContent.DragEnter += new DragEventHandler(UMDEditorMain_DragEnter);
            richTextBoxContent.DragDrop += new DragEventHandler(UMDEditorMain_DragDrop);
            InitSkin();
        }

        private void InitSkin()
        {
            IniFile userConfig = new IniFile(_currentFolder + @"\UserConfig.ini");
            string lastUsedSkin = userConfig.IniReadValue("Skin", "LastUsedSkin");
            if (lastUsedSkin.Length > 0) //use last skin
            {
                skinEngine.SkinFile = _currentFolder + @"\Skins\" + lastUsedSkin + ".ssk";
                CheckUsedSkinMenuItem(lastUsedSkin);
            }
            else //use default skin
            {
                skinEngine.SkinFile = _currentFolder + @"\Skins\PageColor1.ssk";
                userConfig.IniWriteValue("Skin", "LastUsedSkin", "PageColor1");
                CheckUsedSkinMenuItem("PageColor1");
            }
        }

        private void CheckUsedSkinMenuItem(string skinName)
        {
            switch (skinName)
            {
                case "MacOS": MenuItem_Skin_MacOS.Checked = true; break;
                case "OneCyan": MenuItem_Skin_OCyan.Checked = true; break;
                case "PageColor1": MenuItem_Skin_Page1.Checked = true; break;
                case "vistaGreen": MenuItem_Skin_VistaG.Checked = true; break;
                case "WaveColor1": MenuItem_Skin_Wave1.Checked = true; break;
            }
        }

        private void ReadFile()
        {
            try
            {
                this.listViewChapters.Clear();
                this.richTextBoxContent.Clear();
                this.richTextBoxContent.Enabled = true;

                _umdFile.Read(this._path);

                foreach (Chapter chapter in _umdFile.Chapters)
                {
                    ListViewItem item = new ListViewItem(chapter.Title);
                    item.Tag = chapter;
                    this.listViewChapters.Items.Add(item);
                }
                this.listViewChapters.Items[0].Selected = true;
                this._currentChapter = this.listViewChapters.Items[0].Tag as Chapter;
                this.richTextBoxContent.Text = this._currentChapter.Content;

                this.Text = this._fileName + " - " + this.InitFormTitle;
                this.IsModified = false;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void MenuItem_OpenFile_Click(object sender, EventArgs e)
        {
            if (this.IsModified || (this.richTextBoxContent.Modified && this.listViewChapters.Items.Count > 0))
            {
                DialogResult result = MessageBox.Show("文件 " + this._fileName + " 的内容已经改变。\n想要保存文件吗？", "UMD编辑器提示您", MessageBoxButtons.YesNoCancel);
                if (result == DialogResult.Yes)
                {
                    try
                    {
                        SaveFile();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                }
                else if (result == DialogResult.Cancel)
                {
                    return;
                }
            }
            openFileDialog.ShowDialog();
        }

        private void openFileDialog_FileOk(object sender, CancelEventArgs e)
        {
            this._path = openFileDialog.FileName;
            this._fileName = Path.GetFileNameWithoutExtension(this._path);

            ReadFile();
        }

        private void listViewChapters_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.listViewChapters.SelectedIndices.Count > 0)
            {
                if ((this._currentChapter != null) && this.richTextBoxContent.Modified)
                {
                    this._currentChapter.Content = this.richTextBoxContent.Text;
                    this.IsModified = true;
                }
                Chapter tag = (Chapter)this.listViewChapters.SelectedItems[0].Tag;
                this.richTextBoxContent.Text = tag.Content;
                this._currentChapter = tag;
            }
        }

        private void contextMenuChapters_Opening(object sender, CancelEventArgs e)
        {
            this.MenuItemChapterEdit.Enabled = this.listViewChapters.SelectedIndices.Count > 0;
            this.MenuItemChapterDelete.Enabled = this.MenuItemChapterEdit.Enabled;
            this.MenuItemChapterInsert.Enabled = this.MenuItemChapterEdit.Enabled;
        }

        private void MenuItemChapterInsert_Click(object sender, EventArgs e)
        {
            if (this.listViewChapters.SelectedIndices.Count > 0)
            {
                Chapter chapter = new Chapter("新章节", string.Empty);
                ListViewItem item = new ListViewItem("新章节");
                item.Tag = chapter;
                this.listViewChapters.Items.Insert(this.listViewChapters.SelectedIndices[0], item);
                _umdFile.Chapters.Insert(this.listViewChapters.SelectedIndices[0], chapter);

                this.IsModified = true;
            }
        }

        private void MenuItemChapterEdit_Click(object sender, EventArgs e)
        {
            if (this.listViewChapters.SelectedIndices.Count > 0)
            {
                this.listViewChapters.SelectedItems[0].BeginEdit();
            }
        }

        private void listViewChapters_AfterLabelEdit(object sender, LabelEditEventArgs e)
        {
            Chapter tag = (Chapter)this.listViewChapters.Items[e.Item].Tag;
            if ((e.Label != null) && (e.Label.Length != 0))
            {
                tag.Title = e.Label;

                this.IsModified = true;
            }
        }

        private void MenuItemChapterDelete_Click(object sender, EventArgs e)
        {
            if ((this.listViewChapters.SelectedIndices.Count > 0) && (MessageBox.Show("你确认要删除选择的章节及其内容吗？", "删除章节", MessageBoxButtons.YesNo) == DialogResult.Yes))
            {
                foreach (ListViewItem item2 in this.listViewChapters.SelectedItems)
                {
                    Chapter tag = (Chapter)item2.Tag;
                    this.listViewChapters.Items.Remove(item2);
                    _umdFile.Chapters.Remove(tag.Title);

                    this.IsModified = true;
                }
            }

        }

        private void MenuItemChapterAppend_Click(object sender, EventArgs e)
        {
            Chapter chapter = new Chapter("新章节", string.Empty);
            ListViewItem item2 = new ListViewItem("新章节");
            item2.Tag = chapter;
            this.listViewChapters.Items.Add(item2);
            _umdFile.Chapters.Add(chapter);

            this.IsModified = true;
            this.richTextBoxContent.Enabled = true;
            if (this.listViewChapters.Items.Count == 1)
            {
                this.listViewChapters.Items[0].Selected = true;
            }
        }

        private void MenuItem_New_Click(object sender, EventArgs e)
        {
            if (this.IsModified || (this.richTextBoxContent.Modified && this.listViewChapters.Items.Count > 0))
            {
                DialogResult result = MessageBox.Show("文件 " + this._fileName + " 的内容已经改变。\n想要保存文件吗？", "UMD编辑器提示您", MessageBoxButtons.YesNoCancel);
                if (result == DialogResult.Yes)
                {
                    try
                    {
                        SaveFile();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                }
                else if (result == DialogResult.Cancel)
                {
                    return;
                }
            }
            this.IsModified = false;
            this.listViewChapters.Clear();
            this.richTextBoxContent.Clear();
            this.richTextBoxContent.Enabled = false;
            this._currentChapter = null;
            this._fileName = string.Empty;
            this._path = string.Empty;
            _umdFile = new UMDFile();
            this.Text = "无标题" + " - " + this.InitFormTitle;
        }

        private bool SaveFile()
        {
            ListViewItem item = this.listViewChapters.SelectedItems.Count > 0 ? this.listViewChapters.SelectedItems[0] : this.listViewChapters.FocusedItem;
            Chapter tag = (Chapter)item.Tag;
            tag.Content = this.richTextBoxContent.Text;

            if (_path.Length == 0)
            {
                if (this.saveFileDialog.ShowDialog() != DialogResult.OK)
                {
                    return false;
                }
                else
                {
                    this.Text = _fileName + " - " + this.InitFormTitle;
                }
            }
            _umdFile.Save(this._path, true);
            this.IsModified = false;
            this.richTextBoxContent.Modified = false;
            return true;
        }

        private void MenuItem_Save_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.listViewChapters.Items.Count < 1 && this.richTextBoxContent.Text.Trim().Length < 1)
                {
                    MessageBox.Show("温馨提示：请确认有文件内容再使用保存功能！");
                    return;
                }
                if (SaveFile())
                {
                    MessageBox.Show("已保存完毕！");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

        private void MenuItem_Exit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void UMDEditorMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (this.IsModified || (this.richTextBoxContent.Modified && this.listViewChapters.Items.Count > 0))
            {
                DialogResult result = MessageBox.Show("文件 " + this._fileName + " 的内容已经改变。\n想要保存文件吗？", "UMD编辑器提示您", MessageBoxButtons.YesNoCancel);
                if (result == DialogResult.Yes)
                {
                    try
                    {
                        SaveFile();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                }
                else if (result == DialogResult.Cancel)
                {
                    e.Cancel = true;
                }
            }
        }

        private void saveFileDialog_FileOk(object sender, CancelEventArgs e)
        {
            this._path = saveFileDialog.FileName;
            if (Path.GetExtension(saveFileDialog.FileName).ToLower() != ".umd")
            {
                this._path = Path.ChangeExtension(saveFileDialog.FileName, ".umd");
            }
            this._fileName = Path.GetFileNameWithoutExtension(_path);
            _umdFile.Title = _fileName;
            _umdFile.Author = Environment.UserName;
        }

        private void MenuItem_About_Click(object sender, EventArgs e)
        {
            AboutBox aboutbox = new AboutBox();
            aboutbox.ShowDialog();
        }

        private void toolStripButtonExportToTxt_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.listViewChapters.Items.Count < 1 && this.richTextBoxContent.Text.Trim().Length < 1)
                {
                    MessageBox.Show("温馨提示：请确认有文件内容再使用导出功能！");
                    return;
                }

                ListViewItem item = this.listViewChapters.SelectedItems.Count > 0 ? this.listViewChapters.SelectedItems[0] : this.listViewChapters.FocusedItem;
                Chapter tag = (Chapter)item.Tag;
                tag.Content = this.richTextBoxContent.Text;

                if (this.saveFileDialogExport.ShowDialog() == DialogResult.OK)
                {
                    MessageBox.Show("成功导出为txt文本文件！");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

        private void saveFileDialogExport_FileOk(object sender, CancelEventArgs e)
        {
            string exportPath = saveFileDialogExport.FileName;
            if (Path.GetExtension(saveFileDialogExport.FileName).ToLower() != ".txt")
            {
                exportPath = Path.ChangeExtension(saveFileDialogExport.FileName, ".txt");
            }

            StringBuilder content = new StringBuilder();
            foreach (ListViewItem item in this.listViewChapters.Items)
            {
                content.Append((item.Tag as Chapter).Content + "\n");
            }

            StreamWriter sw = new StreamWriter(exportPath);
            sw.Write(content.Replace("\n", Environment.NewLine));
            sw.Flush();
            sw.Close();
        }

        /// <summary>
        /// txt文件快速生成umd文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolButtonTxtToUmd_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.openFileDialogTxt.ShowDialog() == DialogResult.OK)
                {
                    if (TxtToUmd(openFileDialogTxt.FileName))
                    {
                        MessageBox.Show("温馨提示：选择的txt文件已成功转成umd文件！");
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

        public bool TxtToUmd(string txtFilePath)
        {
            string txtFileName = Path.GetFileNameWithoutExtension(txtFilePath);
            string toUmdPath = Path.GetDirectoryName(txtFilePath);

            StreamReader sr = new StreamReader(txtFilePath, Encoding.Default);
            string content = sr.ReadToEnd();
            sr.Close();

            StringBuilder sb = new StringBuilder(content);
            sb = sb.Replace(Environment.NewLine, "\n");

            UMDFile umdFile = new UMDFile();
            umdFile.Title = txtFileName;
            umdFile.Author = Environment.UserName;
            Chapter chapter = new Chapter(txtFileName, sb.ToString());
            umdFile.Chapters.Add(chapter);

            umdFile.Save(toUmdPath + @"\" + txtFileName + ".umd", true);

            return true;
        }

        #region DragEvent

        private void UMDEditorMain_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Link;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }

        private void UMDEditorMain_DragDrop(object sender, DragEventArgs e)
        {
            try
            {
                string path = ((System.Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString();
                if (File.Exists(path))
                {
                    string extensionName = Path.GetExtension(path).ToLower();
                    if (extensionName == ".txt")
                    {
                        if (DialogResult.Yes == MessageBox.Show("你确认要把该文件生成为umd格式的文件吗？", "UMD编辑器提示您", MessageBoxButtons.YesNo))
                        {
                            if (TxtToUmd(path))
                            {
                                MessageBox.Show("温馨提示：选择的txt文件已成功转成umd文件！");
                            }
                        }
                    }
                    else if (extensionName == ".umd")
                    {
                        if (this.IsModified || (this.richTextBoxContent.Modified && this.listViewChapters.Items.Count > 0))
                        {
                            DialogResult result = MessageBox.Show("文件 " + this._fileName + " 的内容已经改变。\n想要保存文件吗？", "UMD编辑器提示您", MessageBoxButtons.YesNoCancel);
                            if (result == DialogResult.Yes)
                            {
                                if (!SaveFile())
                                {
                                    e.Effect = DragDropEffects.None;
                                    return;
                                }
                            }
                            else if (result == DialogResult.Cancel)
                            {
                                e.Effect = DragDropEffects.None;
                                return;
                            }
                        }

                        this._path = path;
                        this._fileName = Path.GetFileNameWithoutExtension(this._path);
                        ReadFile();
                    }
                    else
                    {
                        MessageBox.Show("温馨提示：编辑器不支持该文件格式！");
                    }
                }

                e.Effect = DragDropEffects.None;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

        #endregion


        #region Extension

        private void LinkWithExtension()
        {
            try
            {
                string appPath = Application.ExecutablePath;

                RegistryKey key = Registry.ClassesRoot.OpenSubKey(KEYNAME, true);
                if (key != null)
                {
                    Registry.ClassesRoot.DeleteSubKeyTree(KEYNAME);
                }
                key = Registry.ClassesRoot.CreateSubKey(KEYNAME);
                key.SetValue("", KEYVALUE);
                key = key.CreateSubKey("shell");
                key = key.CreateSubKey("open");
                key = key.CreateSubKey("command");
                key.SetValue("", appPath + " %1");

                //set icon
                key = Registry.ClassesRoot.OpenSubKey(KEYNAME, true);
                key = key.CreateSubKey("DefaultIcon");
                key.SetValue("", appPath);

                if (Registry.ClassesRoot.OpenSubKey(".umd") == null)
                {
                    key = Registry.ClassesRoot.CreateSubKey(".umd");
                    key.SetValue("", KEYNAME);
                }
                else
                {
                    key = Registry.ClassesRoot.OpenSubKey(".umd", true);
                    key.SetValue("", KEYNAME);
                }

                SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSH,
            IntPtr.Zero, IntPtr.Zero);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

        private bool checkIsRegisted()
        {
            try
            {
                RegistryKey keyF = Registry.ClassesRoot.OpenSubKey(".umd");
                RegistryKey keyP = Registry.ClassesRoot.OpenSubKey(KEYNAME);
                bool flag = false;
                if (keyF != null && keyP != null)
                {
                    RegistryKey key = keyP.OpenSubKey("shell", true).OpenSubKey("open", true).OpenSubKey("command", true);
                    if (key.GetValue("").ToString() != (Application.ExecutablePath + " %1"))
                    {
                        key.SetValue("", Application.ExecutablePath + " %1");
                        flag = true;
                    }
                    key = keyP.OpenSubKey("DefaultIcon", true);
                    if (key == null)
                    {
                        key = Registry.ClassesRoot.OpenSubKey(KEYNAME, true).CreateSubKey("DefaultIcon");
                        key.SetValue("", Application.ExecutablePath);
                        flag = true;
                    }
                    if (flag)
                    {
                        SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSH,
               IntPtr.Zero, IntPtr.Zero);
                    }
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
                return true;
            }
        }

        #endregion

        #region Select Skin

        private void SetSkin(string skinName)
        {
            IniFile userConfig = new IniFile(_currentFolder + @"\UserConfig.ini");
            skinEngine.SkinFile = _currentFolder + @"\Skins\" + skinName + ".ssk";
            userConfig.IniWriteValue("Skin", "LastUsedSkin", skinName);
        }

        private void MenuItem_Skin_MacOS_Click(object sender, EventArgs e)
        {
            try
            {
                SetSkin("MacOS");
                CheckSelectedSkin(MenuItem_Skin_MacOS.Name);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

        private void MenuItem_Skin_OCyan_Click(object sender, EventArgs e)
        {
            try
            {
                SetSkin("OneCyan");
                CheckSelectedSkin(MenuItem_Skin_OCyan.Name);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

        private void MenuItem_Skin_Page1_Click(object sender, EventArgs e)
        {
            try
            {
                SetSkin("PageColor1");
                CheckSelectedSkin(MenuItem_Skin_Page1.Name);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

        private void MenuItem_Skin_VistaG_Click(object sender, EventArgs e)
        {
            try
            {
                SetSkin("vistaGreen");
                CheckSelectedSkin(MenuItem_Skin_VistaG.Name);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

        private void MenuItem_Skin_Wave1_Click(object sender, EventArgs e)
        {
            try
            {
                SetSkin("WaveColor1");
                CheckSelectedSkin(MenuItem_Skin_Wave1.Name);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

        private void CheckSelectedSkin(string itemName)
        {
            foreach (ToolStripMenuItem item in MenuItem_Skin.DropDownItems)
            {
                item.Checked = item.Name == itemName;
            }
        }

        #endregion



    }
}